home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / IFC_112 / netscape / application / TextViewHTMLContainer.java < prev    next >
Encoding:
Text File  |  1999-05-28  |  11.9 KB  |  331 lines  |  [TEXT/CWIE]

  1. // TextViewHTMLContainer.java
  2. // By Ned Etcode
  3. // Copyright 1996, 1997 Netscape Communications Corp.  All rights reserved.
  4.  
  5. package netscape.application;
  6. import netscape.util.*;
  7.  
  8.  
  9. /** Instances of this class are used to store containers like STRONG or LI
  10.   * If you need to add some support for another container, subclass
  11.   * TextViewHTMLContainer and use <b>TextView.setHTMLContainerClass()</b> to
  12.   * tell TextView to use your subclass.
  13.   * @note 1.0 changes
  14.   */
  15. public abstract class TextViewHTMLContainer extends TextViewHTMLElement {
  16.     /** The marker for this container */
  17.     String marker;
  18.  
  19.     /** Attributes for this marker */
  20.     String attributes;
  21.  
  22.     /** Children for this marker */
  23.     Object children[] = new Object[0];
  24.  
  25.     /** Prefix cache for this container */
  26.     String prefix = null;
  27.  
  28.     /** Suffix cache for this container */
  29.     String suffix   = null;
  30.  
  31.     /** Length cache. */
  32.     int lengths[];
  33.  
  34.     /** Public methods */
  35.  
  36.     /** You can override this method to return what string should prefix the
  37.       * container.  This method is usualy used to add extra characters like
  38.       * carriage returns. For example, Headers always start with a cariage
  39.       * return. This method for an header should return a cariage return.
  40.       * <b>context</b> is the context <b>lastchar</b> is the last character
  41.       * added to the textView. It is often useful to check if lastChar is '\n'
  42.       * before adding another '\n' The default implementation returns nothing.
  43.       *
  44.       */
  45.      public String prefix(Hashtable context, char lastChar) {
  46.          return "";
  47.      }
  48.  
  49.     /** You can override this method to return what string should suffix the
  50.       * container.  This method is usualy used to add extra characters like
  51.       * carriage returns. For example, Headers always end with a cariage return.
  52.       * This method for an header should return a cariage return. <b>context</b>
  53.       * is the context <b>lastchar</b> is the last character added to the
  54.       * textView. It is often useful to check if lastChar is '\n' before adding
  55.       * another '\n' The default implementation returns nothing.
  56.       *
  57.       */
  58.      public String suffix(Hashtable context, char lastChar) {
  59.          return "";
  60.      }
  61.  
  62.     /** Setup the context for children. Override this method and add or change
  63.       * any key if you want to add some state for children. The default
  64.       * implementation does nothing.
  65.       *
  66.       */
  67.     public void setupContext(Hashtable context) {
  68.     }
  69.  
  70.     /**
  71.      *  Cleanup the context. If you have added some state in setupContext,
  72.      *  you should override this method and remove any state added during
  73.      *  setupContext()
  74.      *  The default implementation does nothing
  75.      */
  76.     public void cleanupContext(Hashtable context) {
  77.     }
  78.  
  79.     /**
  80.      *  Compute the TextView attributes for the prefix according to the
  81.      *  context and initial attributes.
  82.      *  Return the new attributes. The default implementation
  83.      *  returns <b> initialAttributes </b>.
  84.      *  If you need to change the attributes, you should clone <b>initialAttributes</b> and
  85.      *  return a new hashtable.
  86.      *  textView is the TextView for which the HTML is parsed.
  87.      */
  88.     public Hashtable attributesForPrefix(Hashtable context,Hashtable initialAttributes,
  89.                                          TextView textView) {
  90.         return initialAttributes;
  91.     }
  92.  
  93.     /** Compute the TextView attributes for the container contents according to
  94.       * the context and initial attributes.  Return the new attributes. The
  95.       * default implementation returns <b>initialAttributes</b> If you need to
  96.       * change the attributes, you should clone <b>initialAttributes</b> and
  97.       * return a new hashtable. textView is the TextView for which the HTML is
  98.       * parsed.
  99.       *
  100.       */
  101.     public Hashtable attributesForContents(Hashtable context,
  102.                                            Hashtable initialAttributes,
  103.                                            TextView textView) {
  104.         return initialAttributes;
  105.     }
  106.  
  107.     /** Compute the TextView attributes for the suffix according to the context
  108.       * and initial attributes.  Return the new attributes. The default
  109.       * implementation returns <b> initialAttributes </b>  If you need to change
  110.       * the attributes, you should clone <b>initialAttributes</b> and return a
  111.       * new hashtable.  textView is the TextView for which the HTML is parsed.
  112.       *
  113.       */
  114.     public Hashtable attributesForSuffix(Hashtable context,Hashtable initialAttributes,
  115.                                          TextView textView) {
  116.         return initialAttributes;
  117.     }
  118.  
  119.  
  120.     /** Return the string for all children.
  121.       * The default implementation concatenates all children's strings and
  122.       * will fill the lengths cache with the appropriate lengths.
  123.       * The lengths cache is used to speedup the attributes setting phase.
  124.       * You need to override this method only when implementating markers
  125.       * producing attachment like Tables and TextArea. In this case you
  126.       * want to return TextView.TEXT_ATTACHMENT_STRING.
  127.       *
  128.       */
  129.      public String string(Hashtable context) {
  130.          FastStringBuffer fb = new FastStringBuffer();
  131.          int i,c;
  132.          int length = 0;
  133.  
  134.          if( children.length > 0 )
  135.              lengths = new int[children.length];
  136.  
  137.          for(i = 0 , c = children.length ; i < c ; i++ ) {
  138.              ((TextViewHTMLElement)children[i]).appendString(context,fb);
  139.              if( i == 0 ) {
  140.                  lengths[i] = fb.length();
  141.                  length = lengths[i];
  142.              } else {
  143.                  lengths[i] = fb.length() - length;
  144.                  length += lengths[i];
  145.              }
  146.          }
  147.          return fb.toString();
  148.      }
  149.  
  150.     /** Return the children for this container.
  151.       *
  152.       */
  153.     public Object[] children() {
  154.         return children;
  155.     }
  156.  
  157.     /** Convenience to return the children for this container
  158.       * inside a Vector.
  159.       *
  160.       */
  161.     public Vector childrenVector() {
  162.         Vector v = new Vector();
  163.         int i;
  164.  
  165.         for(i=0; i < children.length ; i++)
  166.             v.addElement(children[i]);
  167.         return v;
  168.     }
  169.  
  170.     /** Return the marker for this container */
  171.     public String marker() {
  172.         return marker;
  173.     }
  174.  
  175.     /** Return the HTML attributes in an hashtable.
  176.       * Ex: for <foo bar=1> ... </foo> will produce an hashtable with
  177.       * one key "FOO" (note upper case) with a value "1" as a string
  178.       *
  179.       */
  180.     public Hashtable attributes() {
  181.         return hashtableForHTMLAttributes(attributes);
  182.     }
  183.  
  184.  
  185.     /* Private methods */
  186.  
  187.     /** When parsing HTML,TextView will allocate one instance of TextViewHTMLContainer
  188.       * for each recognized HTML containers and then call setMarker(), setAttributes() and
  189.       * setChildren() on it.
  190.       * The default implementation of setMarker() is to store the marker into the <b>
  191.       * marker</b> instance variable.
  192.       * @private
  193.       */
  194.     public void setMarker(String aString) {
  195.         marker = aString;
  196.     }
  197.  
  198.     /** When parsing HTML,TextView will allocate one instance of TextViewHTMLContainer
  199.       * for each recognized HTML containers and then call setMarker(), setAttributes() and
  200.       * setChildren() on it.
  201.       * The default implementation of setAttributes() is to store the attributes into the <b>
  202.       * attributes</b> instance variable.
  203.       * @private
  204.       */
  205.     public void setAttributes(String attr) {
  206.         attributes = attr;
  207.     }
  208.  
  209.     /** When parsing HTML,TextView will allocate one instance of TextViewHTMLContainer
  210.       * for each recognized HTML containers and then call setMarker(), setAttributes() and
  211.       * setChildren() on it.
  212.       * The default implementation of setChildren() is to store the children into the <b>
  213.       * children</b> instance variable.
  214.       * @private
  215.       */
  216.     public void setChildren(Object children[]) {
  217.         if(children == null)
  218.             this.children = new Object[0];
  219.         else
  220.             this.children = children;
  221.     }
  222.  
  223.     void appendString(Hashtable context,FastStringBuffer fb) {
  224.       char lastChar = (char) 0;
  225.  
  226.       if( fb.length() > 0 )
  227.           lastChar = fb.charAt(fb.length() - 1);
  228.  
  229.       prefix = prefix(context,lastChar);
  230.       if( prefix != null && prefix.length() > 0 )
  231.           fb.append(prefix);
  232.  
  233.       if( children != null ) {
  234.         setupContext(context);
  235.         fb.append(string(context));
  236.         cleanupContext(context);
  237.       }
  238.  
  239.       if( fb.length() > 0 )
  240.           lastChar = fb.charAt(fb.length() - 1);
  241.  
  242.       suffix = suffix(context,lastChar);
  243.       if(suffix != null && suffix.length() > 0)
  244.           fb.append(suffix);
  245.     }
  246.  
  247.  
  248.     /** Set the attributes for the string starting at index index
  249.       *
  250.       */
  251.     void setAttributesStartingAt(int index, Hashtable initialAttributes,TextView target,
  252.                                         Hashtable context) {
  253.         int i,c,offset = 0;
  254.         Hashtable newAttributes = null;
  255.  
  256.         if( prefix != null  && prefix.length() > 0) {
  257.             newAttributes = attributesForPrefix(context,initialAttributes,target);
  258.             if(newAttributes != initialAttributes)
  259.                 target.addAttributesForRange(newAttributes,new Range(index,prefix.length()));
  260.             offset += prefix.length();
  261.         }
  262.  
  263.         if( appliesAttributesToChildren() ) {
  264.             if( children != null && children.length > 0 && lengths != null ) {
  265.                 newAttributes = attributesForContents(context,initialAttributes,target);
  266.                 setupContext(context);
  267.                 for(i=0,c=children.length ; i < c ; i++ ) {
  268.                     ((TextViewHTMLElement)children[i]).setAttributesStartingAt( index + offset,
  269.                                                                                 newAttributes,
  270.                                                                                 target,context);
  271.                     if( lengths != null )
  272.                         offset += lengths[i];
  273.                     else
  274.                         offset += ((TextViewHTMLElement)children[i]).string(context).length();
  275.                 }
  276.                 cleanupContext(context);
  277.             } else { /** Apply attributes when Length is 0
  278.                       *  this can happen for a link destination
  279.                       *  attribute.
  280.                       */
  281.                 Range r = TextView.allocateRange(index + offset,0);
  282.                 newAttributes = attributesForContents(context,initialAttributes,target);
  283.                 target.addAttributesForRange(newAttributes,r);
  284.                 TextView.recycleRange( r );
  285.             }
  286.         } else {
  287.             newAttributes = attributesForContents(context,initialAttributes,target);
  288.             if(newAttributes != initialAttributes)
  289.                 target.addAttributesForRange(newAttributes,new Range(index + offset,
  290.                                                                      string(context).length()));
  291.         }
  292.  
  293.         if( suffix != null && suffix.length() > 0 ) {
  294.             newAttributes = attributesForSuffix(context,initialAttributes,target);
  295.             if( newAttributes != initialAttributes )
  296.                 target.addAttributesForRange(newAttributes,new Range(index + offset,suffix.length()));
  297.             offset += suffix.length();
  298.         }
  299.     }
  300.  
  301.     /** Return <b>true</b> if this marker should applies contents attributes to
  302.       * children.  <b>False</b> if attributes should be applied to the result of
  303.       * string(contents). The default value is true. Override this method and
  304.       * return false, if you are implementing a container that replaces its
  305.       * children with a TextAttachment.
  306.       *
  307.       */
  308.     public boolean appliesAttributesToChildren() {
  309.         return true;
  310.     }
  311.  
  312.     /**
  313.      * @private
  314.      */
  315.     public void setString(String aString) {
  316.     }
  317.  
  318.  
  319.  
  320.     public String toString() {
  321.         StringBuffer sb = new StringBuffer();
  322.         int i;
  323.  
  324.         sb.append(marker + attributes);
  325.         for(i=0; i < children.length ; i++ )
  326.             sb.append(children[i].toString());
  327.         return sb.toString();
  328.     }
  329. }
  330.  
  331.